package com.tangding.hprose.api.server.command;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.tangding.common.exception.GException;
import com.tangding.common.holder.SpringContextHolder;
import com.tangding.common.tools.ErrorConstants;
import com.tangding.service.dao.role.PermissionRepository;
import com.tangding.service.dao.role.RoleRepository;
import com.tangding.service.dao.user.UserRepository;
import com.tangding.service.entity.role.Permission;
import com.tangding.service.entity.role.Role;
import com.tangding.service.entity.user.User;

/**
 * @description 
 *
 * @author Ranger
 * @version 2017年11月21日_下午1:59:41
 *
 */
public interface Command {
	
	Response exe(Object... params) throws GException;
	
	ExecutorService poolExe = Executors.newScheduledThreadPool(Runtime.getRuntime().availableProcessors() * 2);
	
	Map<Class<? extends Command>, String[]> cmd2Auth = new HashMap<Class<? extends Command>, String[]>(){
		{
		}
	};
	
	Map<String, String[]> redirectCmd2Auth = new HashMap<String, String[]>(){
		{
			put("SettingsLimit", new String[]{"sysControl"});
			put("UpdateGamesSettings", new String[]{"sysControl"});
			put("UpdateGamesEntrySettings", new String[]{"sysControl"});
			put("QueryGamesSettings", new String[]{"sysControl"});
			put("QueryGameSettings", new String[]{"sysControl"});
			put("SysMsgs", new String[]{"sysControl"});
			put("AddNeon", new String[]{"sysControl"});
			put("AddNotice", new String[]{"sysControl"});
			put("DelNeon", new String[]{"sysControl"});
			put("DelNotice", new String[]{"sysControl"});
			put("AddAccount", new String[]{"sysControl"});
			put("StopAccount", new String[]{"sysControl"});
			put("DelAccount", new String[]{"sysControl"});
			put("QueryAllAccount", new String[]{"sysControl"});
			put("QueryOneAccount", new String[]{"sysControl"});
			put("GiveOperate", new String[]{"sysControl"});
			put("AddARobot", new String[]{"sysControl"});
			put("DelARobot", new String[]{"sysControl"});
			put("CanGive", new String[]{"sysControl"});
			put("QueryGamesData", new String[]{"sysControl"});
			
			put("ForceOutline", new String[]{"control"});
			put("ControlPlayer", new String[]{"control"});
			put("PrefabControl", new String[]{"control"});
			put("ReleaseAGun", new String[]{"control"});
			put("InsertControl", new String[]{"control"});
			put("ZHXControl", new String[]{"control"});
			put("BigRewardControl", new String[]{"control"});
			put("CancelBigReward", new String[]{"control"});
		}
	};
	
	default boolean hasAuth(String uid, String... permissions) throws GException {
		UserRepository userRepository = SpringContextHolder.getBean(UserRepository.class);
		RoleRepository roleRepository = SpringContextHolder.getBean(RoleRepository.class);
		PermissionRepository permissionRepository = SpringContextHolder.getBean(PermissionRepository.class);
		User user = userRepository.getUserByUid(uid);
		if (user == null) {
			throw new GException(ErrorConstants.ERR_LACK_PERMISSION);
		}
		
		Set<Integer> roleIds = user.getRoles();
		if (roleIds == null || roleIds.size() == 0) {
			throw new GException(ErrorConstants.ERR_LACK_PERMISSION);
		}
		
		Set<Integer> permissionIds = new HashSet<>();
		for (Integer roleId : roleIds) {
			Role role = roleRepository.getRole(roleId);
			if (role != null) {
				permissionIds.addAll(role.getPermission());
			}
		}
		
		if (permissionIds.size() == 0) {
			throw new GException(ErrorConstants.ERR_LACK_PERMISSION);
		}
		
		if (permissions != null && permissions.length > 0) {//需要的权限列表,如果没有登记，直接返回true
			for (String permission : permissions) {
				boolean found = false;
				for (Integer id : permissionIds) {
					Permission per = permissionRepository.getPermission(id);
					if (permission.equals(per.getKey())) {
						found = true;
					}
				}
				if (!found) {
					throw new GException(ErrorConstants.ERR_LACK_PERMISSION);
				}
			}
		}
		return true;
	}
	
	default Response doResponseSucc(Object data) {
		Response response = new Response();
		response.setCode(ErrorConstants.SUCC);
		response.setData(data);
		return response;
	}
	
	default Response doResponseSucc() {
		Response response = new Response();
		response.setCode(ErrorConstants.SUCC);
		return response;
	}
	
	default Response doResponseError() {
		Response response = new Response();
		response.setCode(ErrorConstants.FAIL);
		response.setMsg(ErrorConstants.getDesc(ErrorConstants.FAIL));
		return response;
	}
	
	default Response doResponseError(int err) {
		Response response = new Response();
		response.setCode(err);
		response.setMsg(ErrorConstants.getDesc(err));
		return response;
	}
	
	default Response doResponseError(int err, String msg) {
		Response response = new Response();
		response.setCode(err);
		response.setMsg(msg);
		return response;
	}
}
